/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package aiaudio.database.tables;

import aiaudio.database.Family;
import aiaudio.database.Family;
import aiaudio.database.qualifiers.DoubleQualifier;
import aiaudio.database.qualifiers.IntQualifier;
import aiaudio.database.qualifiers.LongQualifier;
import aiaudio.database.qualifiers.Qualifier;
import aiaudio.database.qualifiers.StringQualifier;
import java.io.IOException;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;

/**
 *
 * @author nastya
 */
public abstract class TableStructure {

    TableStructure() {
    }

    protected static final long UNMODIFIABLE_TIMESTAMP = 1L;

    public void createInDatbase(boolean dropIfExists) {
        Family[] families = getAllFamilies();
    }

    public abstract Family[] getAllFamilies();
    
    public static final ArtistsListTable ArtistList = new ArtistsListTable();
    public static final UsersListTable UsersList = new UsersListTable();
    public static final RatingsListTable RatingList = new RatingsListTable();
    public static final DataMetricsTable DataMetrics = new DataMetricsTable();
    public static final TimeMetricsTable TimeMetrics = new TimeMetricsTable();
    public static final SocialTable Social = new SocialTable();

    public static final RatingsMatrixTable RatingMatrix = new RatingsMatrixTable();

    public static final NeighbourGroupToUserTable NeighbourGroupToUser = new NeighbourGroupToUserTable();
    public static final NeighbourUserToGroupTable NeighbourUserToGroup = new NeighbourUserToGroupTable();
    
    public static final RecommendationListTable RecommendationListTable = new RecommendationListTable();
    public static final StatisticsTable StatisticsTable = new StatisticsTable();
    
    public static final ReduceDictionaryTable ReduceDictionary = new ReduceDictionaryTable();
    public static final ReduceResultTable ReduceResult = new ReduceResultTable();
    
    public static final TemporaryMatrixTable TemporaryMatrix = new TemporaryMatrixTable();
    public static final TemporaryTable Temporary = new TemporaryTable();
    

    protected static <ValueType> ValueType getSingleColumnValue(HTable tableInstance, byte[] id,
            Family family, Qualifier<ValueType> qualifier) throws IOException {
        Get get = new Get(id);
        get.addColumn(family.getNameAsBytes(), qualifier.getNameAsBytes());
        Result result = tableInstance.get(get);
        byte[] value = result.getValue(family.getNameAsBytes(), qualifier.getNameAsBytes());
        return qualifier.parse(value);

    }

    protected static void addData(Put put,
            Family family, StringQualifier qualifier, String value) {
        put.add(family.getNameAsBytes(), qualifier.getNameAsBytes(), Bytes.toBytes(value));
    }

    protected static void addData(Put put,
            Family family, LongQualifier qualifier, long value) {
        put.add(family.getNameAsBytes(), qualifier.getNameAsBytes(), Bytes.toBytes(value));
    }

    protected static void addData(Put put,
            Family family, IntQualifier qualifier, int value) {
        put.add(family.getNameAsBytes(), qualifier.getNameAsBytes(), Bytes.toBytes(value));
    }

    protected static void addData(Put put,
            Family family, DoubleQualifier qualifier, double value) {
        put.add(family.getNameAsBytes(), qualifier.getNameAsBytes(), Bytes.toBytes(value));
    }

    protected static void addDataSavePreviousRow(Put put,
            Family family, StringQualifier qualifier, String value) {
        put.add(family.getNameAsBytes(), qualifier.getNameAsBytes(),
                UNMODIFIABLE_TIMESTAMP, Bytes.toBytes(value));
    }

    protected static void addDataSavePreviousRow(Put put,
            Family family, LongQualifier qualifier, long value) {
        put.add(family.getNameAsBytes(), qualifier.getNameAsBytes(),
                UNMODIFIABLE_TIMESTAMP, Bytes.toBytes(value));
    }

    protected static void addDataSavePreviousRow(Put put,
            Family family, IntQualifier qualifier, int value) {
        put.add(family.getNameAsBytes(), qualifier.getNameAsBytes(),
                UNMODIFIABLE_TIMESTAMP, Bytes.toBytes(value));
    }

    protected static void addDataSavePreviousRow(Put put,
            Family family, DoubleQualifier qualifier, double value) {
        put.add(family.getNameAsBytes(), qualifier.getNameAsBytes(),
                UNMODIFIABLE_TIMESTAMP, Bytes.toBytes(value));
    }
    
    protected static <ValueType> ValueType getValue(Result result, Family family, Qualifier<ValueType> qualifier){
        byte[] value = result.getValue(family.getNameAsBytes(), qualifier.getNameAsBytes());
        return qualifier.parse(value);
    }
    protected static <ValueType> byte[] getValueAsBytes(Result result, Family family, Qualifier<ValueType> qualifier){
        return result.getValue(family.getNameAsBytes(), qualifier.getNameAsBytes());
    }
    
    protected static void incrementColumnValue(HTable tableInstance, String rowId, Family family, LongQualifier column, long value) throws IOException {
        tableInstance.incrementColumnValue(Bytes.toBytes(rowId), family.getNameAsBytes(), column.getNameAsBytes(), value);
    }
    
}
